home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
xlib
/
cmapfog.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
11KB
|
410 lines
/*
* Copyright (c) 1995, Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the name of Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
* POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/*
* cmapfog.c
*
* this sample code shows how to do depthcueing using fog in OpenGL with
* color index mode. you can use the arrow keys to adjust the start and
* end of the fog effect, the up-arrow key increments that FOG_START value,
* the down-arrow key decrements FOG_START. the left arrow key increments the
* FOG_END value, the righ-arrow decrements it. The 'q' key queries the
* current FOG_START and FOG_END values. as usual, the 'Esc' key will
* exit. it should help give you an idea as to how the start and end values
* for fog will affect your scene as well as how to set up a color ramp
* and get OpenGL to index into it correctly. the default color ramp
* is 32 entries wide
*/
#include <GL/glx.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/keysym.h>
/*
* double buffered, color index visual attributes
*/
static int CIattributes[] = {
GLX_DEPTH_SIZE, 1,
GLX_DOUBLEBUFFER,
None,
};
/*
* global stuff
*/
#define COLOR_OFFSET 97
float MY_FOG_START = 0.0;
float MY_FOG_END = 20.0;
static long W = 700, H = 700;
static long size, mode;
Display *dpy;
Window window;
int rampSize = 32; /* default ramp size, 32 entries */
/*
* this routine does the actual drawing
*/
static void DoDisplay(void)
{
GLint i, n;
/*
* enable z buffer depth test
*/
glEnable(GL_DEPTH_TEST);
glDepthRange(0, 0xfffff);
glDepthFunc(GL_LESS);
/*
* set up projection matrix
*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-30.0, 50.0, -10.0, 50.0, -50.0, 50.0);
/*
* set up model view matrix
*/
glMatrixMode(GL_MODELVIEW);
/*
* just to make things interesting, push down a matrix and
* apply a 35 degree rotation on x, y & z axis so that the
* object drawn has some parts closer, some farther away
*/
glPushMatrix();
glRotated(35, 1, 1, 1);
/*
* clear buffers
*/
glIndexi(0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
/*
* now, turn on fog, linear fog, set fog start & end values as
* well as color index to the start of the ramp.
*/
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_LINEAR);
/*
* set GL_FOG_INDEX to the rampSize - 1. this is because say we
* have 32 entries in our ramp, the fragment color index will be
* in the range 0 - 31.
*/
glFogi(GL_FOG_INDEX, rampSize-1);
glFogf(GL_FOG_START, MY_FOG_START);
glFogf(GL_FOG_END, MY_FOG_END);
/*
* set color to first color in the ramp, the color of our object
*/
glIndexi(COLOR_OFFSET);
glFrontFace(GL_CW);
/*
* draw a wire-frame pyramid
*/
glBegin(GL_LINE_LOOP);
glVertex3f(0,0,0);
glVertex3f(40,0,0);
glVertex3f(20,40,0);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(0,0,-40);
glVertex3f(40,0,-40);
glVertex3f(20,40,0);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(0,0,0);
glVertex3f(0,0,-40);
glVertex3f(20,40,0);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(40,0,0);
glVertex3f(40,0,-40);
glVertex3f(20,40,0);
glEnd();
glFlush();
glPopMatrix();
/*
* let's see what we did...
*/
glXSwapBuffers(dpy, window);
}
/*
* convenience function, waits for a window to map
* so that we don't try to render into a window that
* hasn't mapped yet.
*/
static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
{
if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
return GL_TRUE;
}
return GL_FALSE;
}
/*
* main routine
*/
int main(long argc, char** argv)
{
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
GLXContext cx;
XEvent event;
GLboolean needDisplay;
int i;
XColor *xc;
float numEnt;
/*
* print out instructions
*/
fprintf(stderr, "\n cmapfog valid commands: ");
fprintf(stderr, "\n up-arrow : increment FOG_START ");
fprintf(stderr, "\n down-arrow : decrement FOG_START ");
fprintf(stderr, "\n left-arrow : increment FOG_END ");
fprintf(stderr, "\n right-arrow: decrement FOG_END ");
fprintf(stderr, "\n 'q' key : query current fog start and end values");
fprintf(stderr, "\n 'Esc' key : exit ");
fprintf(stderr, "\n ");
/*
* if a ramp size has been entered on the command line,
* use it, else default to 32 entries
*/
if (argc > 1)
rampSize = atoi(argv[1]);
else {
fprintf(stderr, "\n using default cmap ramp size of 32.");
fprintf(stderr, "\n to specify ramp size, run:");
fprintf(stderr, "\n cmapfog <ramp size>");
}
if ((rampSize < 1) || (rampSize > 128)) {
fprintf(stderr, "\n number of color ramp entries must be between 1 - 128\n");
exit(-1);
}
fprintf(stderr, "\n ramp size: %d", rampSize);
/*
* connect to display
*/
dpy = XOpenDisplay(0);
if (!dpy) {
fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
return -1;
}
/*
* find appropriate visual
*/
vi = glXChooseVisual(dpy, DefaultScreen(dpy), CIattributes);
if (!vi) {
fprintf(stderr, "No appropriate visual on \"%s\"\n",
getenv("DISPLAY"));
return -1;
}
/*
* create a colormap for our window
*/
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
AllocAll);
/*
* set up attributes and create window
*/
swa.border_pixel = 0;
swa.colormap = cmap;
swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
| KeyReleaseMask;
window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
W, H,
0, vi->depth, InputOutput, vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa);
/*
* need a gl context to render into. don't forget to make it current!
*/
cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
if (!glXMakeCurrent(dpy, window, cx)) {
fprintf(stderr, "Can't make window current to context\n");
return -1;
}
/*
* now for the color ramp. allocate an array of XColor cells and
* fill them in.
*/
xc = (XColor *) malloc(sizeof(XColor) * rampSize);
numEnt = (float) (rampSize-1);
for (i = 0; i < rampSize; i++) {
/* black to white ramp */
xc[i].pixel = i + COLOR_OFFSET;
xc[i].red = (unsigned short) (65535.0 - (65535.0 * (i / numEnt)));
xc[i].green = (unsigned short) (65535.0 - (65535.0 * (i / numEnt)));
xc[i].blue = (unsigned short) (65535.0 - (65535.0 * (i / numEnt)));
xc[i].flags = DoRed | DoGreen | DoBlue;
}
/*
* store ramp into window colormap
*/
XStoreColors(dpy, cmap, xc, rampSize);
/*
* tell the window manager to install this colormap for our window
*/
XSetWMColormapWindows(dpy, window, &window, 1);
/*
* map window and wait for it to map
*/
XMapWindow(dpy, window);
XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
needDisplay = GL_TRUE;
/*
* now watch for X events
*/
for (;;) {
do {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
needDisplay = GL_TRUE;
break;
case ConfigureNotify:
W = event.xconfigure.width;
H = event.xconfigure.height;
needDisplay = GL_TRUE;
break;
case KeyPress:
{
char buf[100];
int rv;
KeySym ks;
rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
switch (ks) {
case XK_Up:
MY_FOG_START++;
if (MY_FOG_START == MY_FOG_END) {
MY_FOG_START--;
fprintf(stderr, "\n fog start = fog end");
}
else {
needDisplay = GL_TRUE;
fprintf(stderr, "\n fog start: %f", MY_FOG_START);
}
break;;
case XK_Down:
MY_FOG_START--;
needDisplay = GL_TRUE;
fprintf(stderr, "\n fog start: %f", MY_FOG_START);
break;;
case XK_Left:
MY_FOG_END++;
needDisplay = GL_TRUE;
fprintf(stderr, "\n fog end: %f", MY_FOG_END);
break;
case XK_Right:
MY_FOG_END--;
if (MY_FOG_END == MY_FOG_START) {
MY_FOG_END++;
fprintf(stderr, "\n fog end = fog start");
}
else {
fprintf(stderr, "\n fog end: %f", MY_FOG_END);
needDisplay = GL_TRUE;
}
break;
case XK_Q:
case XK_q:
fprintf(stderr, "\n\n current fog start: %f", MY_FOG_START);
fprintf(stderr, " current fog end: %f\n", MY_FOG_END);
break;
case XK_Escape:
fprintf(stderr, "\n bye...\n");
return 0;
break;
}
}
break;
}
} while (XPending(dpy) != 0);
/*
* redisplay if needed
*/
if (needDisplay) {
needDisplay = GL_FALSE;
DoDisplay();
}
}
}